package com.freewater.library.lending.reservedsheet.model;

import com.freewater.library.catalogue.model.Book;
import com.freewater.library.common.domain.Nullable;
import com.freewater.library.lending.book.model.BookInstance;
import com.freewater.library.lending.reader.model.Reader;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.Validate;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 预定记录
 */
@Data
@Entity
@NoArgsConstructor
@Table(name = "book_reserved_record",
        uniqueConstraints = {
                @UniqueConstraint(columnNames = {"qr_code", "reserved_by", "reserved_at"})
        })
@EqualsAndHashCode(of = {"qrCode", "reservedBy", "reservedAt"})
public class BookReservedRecord {
    /**
     * 状态：预定中
     */
    private static final int STATUS_RESERVING = 0;
    /**
     * 状态：完成预定
     */
    private static final int STATUS_COMPLETED = 1;
    /**
     * 状态：已取消
     */
    private static final int STATUS_CANCELED = -1;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    /**
     * 二维码
     */
    private String qrCode;
    /**
     * 预定读者ID
     */
    private Long reservedBy;
    /**
     * 预定时间
     */
    private LocalDateTime reservedAt;
    /**
     * 预定读者姓名
     */
    private String reservedByName;
    /**
     * 书ISBN
     */
    private String isbn;
    /**
     * 标题
     */
    private String title;
    /**
     * 副标题
     */
    private String subtitle;
    /**
     * 作者
     */
    private String author;
    /**
     * 出版社
     */
    private String publishingHouse;
    /**
     * 封面图
     */
    private String cover;
    /**
     * 丛书
     */
    private String series;
    /**
     * 状态
     */
    private int status;
    /**
     * 取消原因
     */
    private String cancelReason;
    /**
     * 取消时间
     */
    private LocalDateTime cancelTime;
    /**
     * 完成时间
     */
    private LocalDateTime completeTime;

    public BookReservedRecord(Book book,
                              BookInstance bookInstance,
                              Reader reserveReader,
                              @Nullable LocalDateTime reservedAt) {
        Validate.notNull(book, "书不能为空");
        Validate.notNull(bookInstance, "预定书不能为空");
        Validate.notNull(reserveReader, "预定读者不能为空");
        this.qrCode = bookInstance.getQrCode();
        this.reservedBy = reserveReader.getId();
        this.reservedAt = reservedAt == null ? LocalDateTime.now() : reservedAt;
        this.reservedByName = reserveReader.getName();
        this.isbn = book.getIsbn();
        this.title = book.getTitle();
        this.subtitle = book.getSubtitle();
        this.author = book.getAuthor();
        this.publishingHouse = book.getPublishingHouse();
        this.cover = book.getCover();
        this.series = book.getSeries();
        this.status = STATUS_RESERVING;
    }

    public boolean isReserving() {
        return this.status == STATUS_RESERVING;
    }

    public void checkedOut(LocalDateTime checkOutTime) {
        Validate.notNull(checkOutTime, "借出时间不能为空");
        this.status = STATUS_COMPLETED;
        this.completeTime = checkOutTime;
    }

    public void canceled(LocalDateTime cancelTime, String cancelReason) {
        Validate.notNull(cancelTime, "取消预定时间不能为空");
        Validate.notNull(cancelReason, "取消原因不能为空");
        this.status = STATUS_CANCELED;
        this.cancelTime = cancelTime;
        this.cancelReason = cancelReason;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Unique implements Serializable {
        /**
         * 二维码
         */
        private String qrCode;
        /**
         * 预定读者Id
         */
        private Long reservedBy;
        /**
         * 预定时间
         */
        private LocalDateTime reservedAt;
    }
}
